using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

using WP.DB;
using WP.Commons;

namespace WP.MF.DataAccess
{
    public class MUserMenuDAL
    {

        #region Update user defined menu
        public void UpdateUserMenu(TreeView tvEdit, string strUserMenuName)
        {
            DBAccess dBAccess = new DBAccess(false, true);

            try
            {
                UpdateUserMenu(dBAccess, tvEdit, strUserMenuName);
                dBAccess.CommitTranAndCloseCon();
            }
            catch (Exception e)
            {
                dBAccess.RollbackTranAndClose();
                ExceptionManager.ProcessException(e);
            }
        }

        public void UpdateUserMenu(DBAccess dBAccess, TreeView tvEdit, string strUserMenuName)
        {
            string strSql = string.Empty;
            int intUserMenuNo = 0;
            string strPreKey = string.Empty;
            DataTable dtUserMenu = null;
            DataRow drUserMenu = null;
            TreeNode nodeX = null;

            //ProgressBar.Value = ProgressBar.Min
            //ProgressBar.Visible = True
            //ProgressBar.Refresh
            //ProgressBar.Max = tvwEdit.Nodes.Count + 10

            intUserMenuNo = GetCurUserMenuNo(dBAccess, strUserMenuName);
            DelUsermenu(dBAccess, strUserMenuName);
            strSql = "select * from mUserMenu where UserName='" + SysVar.UserName + "' ";
            strSql+= "and UserMenuName='" + strUserMenuName.Replace("'", "''") + "'";
            dtUserMenu = dBAccess.GetDataTable(strSql);

            //ProgressBar.Value = 5

            nodeX = FirstNode(tvEdit); //.Nodes[0]
            while (nodeX != null)
            {
                drUserMenu = dtUserMenu.NewRow();
                drUserMenu["UserName"] = SysVar.UserName;
                drUserMenu["UserMenuNo"] = intUserMenuNo;
                drUserMenu["UserMenuName"] = strUserMenuName;
                drUserMenu["UserMenuID"] = GetCurKey(tvEdit, nodeX.Name, strPreKey);
                if (nodeX.Tag != null)
                    drUserMenu["MenuId"] = nodeX.Tag.ToString();
                else
                    drUserMenu["MenuId"] = string.Empty;
                drUserMenu["MenuName"] = nodeX.Text;
                strPreKey = drUserMenu["UserMenuID"].ToString();
                nodeX = NextNode(tvEdit, nodeX.Name);

                 DataFunctions.UpdateTable(dBAccess, "UserName,UserMenuNo,UserMenuName,UserMenuID,MenuId,MenuName", "mUserMenu", drUserMenu, FormStatus.AddNew, "RecID", false);
                //ProgressBar.Value = ProgressBar.Value + 1
            }
            ////mblnChange = False

            //ProgressBar.Value = ProgressBar.Max
            //ProgressBar.Visible = False
            //ProgressBar.Value = 0
        }

        private int GetCurUserMenuNo(DBAccess dBAccess, string UserMenuName)
        {
            // get user menu no , if UserMenuName exist , return this UserMenuName' No ,   if not exist return a current No
            int iUserMenuNo = 0;
            DataView dvUserMenu = null;
            string strSql = string.Empty;
            int i = 1;

            strSql = "select distinct UserMenuNo,UserMenuName from mUserMenu where UserName='" + SysVar.UserName + "' order by UserMenuNo";
            dvUserMenu = dBAccess.GetDataTable(strSql).DefaultView;
            
            if (dvUserMenu.Count == 0)
            {
                iUserMenuNo = 1;
                return iUserMenuNo;
            }
            
            dvUserMenu.RowFilter = "UserMenuName='" + UserMenuName + "'";
            if (dvUserMenu.Count != 0)
            {
                iUserMenuNo = CvtFunc.ToInt(dvUserMenu[0]["UserMenuNo"]);
                return iUserMenuNo;
            }
            
            strSql = "select distinct UserMenuNo,UserMenuName from mUserMenu where UserName='" + SysVar.UserName + "' order by UserMenuNo";
            dvUserMenu = dBAccess.GetDataTable(strSql).DefaultView;
            foreach (DataRowView drvUserMenu in dvUserMenu)
            {
                if (i != CvtFunc.ToInt(drvUserMenu["UserMenuNo"])) break;
                i+= 1;
            }
            iUserMenuNo = i;
            return iUserMenuNo;
        }
        private string GetCurKey(TreeView tvEdit, string OldKey, string previousKey)
        {
            // in tvEdit , get current node key from old node key , only use for save user defined menu
            string strCurKey = string.Empty;
            string strPreKey = string.Empty;
            string strTemp = string.Empty;
            int intNo = 1;
            TreeNode nodeX = null;

            if (previousKey == string.Empty)                  // is first node
            {
                strCurKey = "001000000000";
                return strCurKey;
            }

            strPreKey = PreviousNode(tvEdit, OldKey).Name.ToString();
            if (tvEdit.Nodes.Find(OldKey, true)[0].PrevNode == null)       // previous node is this node parent
            {
                if (previousKey.Substring(previousKey.Length - 9) == "000000000")
                    strCurKey = previousKey.Substring(0, 3) + "001000000";
                else if (previousKey.Substring(previousKey.Length - 6) == "000000")
                    strCurKey = previousKey.Substring(0, 6) + "001000";
                else if (previousKey.Substring(previousKey.Length - 3) == "000")
                    strCurKey = previousKey.Substring(0, 9) + "001";

                return strCurKey;
            }

            // previous node is this node brother
            //if (previousKey == "003001001001")
            //{
            //    MessageBox.Show("ddd");
            //}
            if (tvEdit.Nodes.Find(OldKey,true)[0].PrevNode.Name == strPreKey)
            {
                if (previousKey.Substring(previousKey.Length - 9) == "000000000")
                    strCurKey = string.Format("{0:000}", CvtFunc.ToInt(previousKey.Substring(0, 3)) + 1) + "000000000";
                else if (previousKey.Substring(previousKey.Length - 6) == "000000")
                    strCurKey = string.Format("{0:000000}", CvtFunc.ToInt(previousKey.Substring(0, 6)) + 1) + "000000";
                else if (previousKey.Substring(previousKey.Length - 3) == "000")
                    strCurKey = string.Format("{0:000000000}", CvtFunc.ToInt(previousKey.Substring(0, 9)) + 1) + "000";
                else
                    strCurKey = string.Format("{0:000000000000}", CvtFunc.ToLong(previousKey) + 1);

                return strCurKey;
            }

            // previous is not this node brother , and is not parent  , need to find  a parent of  previous node is this node brother
            nodeX = tvEdit.Nodes.Find(strPreKey,true)[0].Parent;
            while (nodeX.Name != tvEdit.Nodes.Find(OldKey,true)[0].PrevNode.Name)
            {
                nodeX = tvEdit.Nodes.Find(nodeX.Name.ToString(),true)[0].Parent;
                intNo += 1;               // intNo max =3 , because this node max has 3 parent
            }
            strTemp = previousKey;
            switch (intNo)
            {
                case 3:
                    strTemp = strTemp.Substring(0, 3);
                    break;

                case 2:
                    if (strTemp.Substring(strTemp.Length - 3) == "000")
                        strTemp = strTemp.Substring(0, 3);
                    else
                        strTemp = strTemp.Substring(0, 6);

                    break;
                case 1:
                    if (strTemp.Substring(strTemp.Length - 6) == "000000")
                        strTemp = strTemp.Substring(0, 3);
                    else if (strTemp.Substring(strTemp.Length - 3) == "000")
                        strTemp = strTemp.Substring(0, 6);
                    else
                        strTemp = strTemp.Substring(0, 9);

                    break;
                default:
                    break;
            }
            strTemp = CvtFunc.ToString(CvtFunc.ToInt(strTemp) + 1);       // this is this node key , but first maybe add 0
            while (BaseFunctions.Mod(strTemp.Length, 3) != 0)   // add 0 in first
            {
                strTemp = "0" + strTemp;
            }
            while (strTemp.Length < 12)
            {
                strTemp += "000";                  // add 000 in last
            }
            // Now , strTemp is current key
            strCurKey = strTemp;
            return strCurKey;
        }
        private TreeNode FirstNode(TreeView tvObject)
        {
            // Function: get tvObject first Node it must be a root
            TreeNode tnFirst = null;
            if (tvObject.Nodes.Count == 0)
                tnFirst = null;
            else
                tnFirst = tvObject.Nodes[0]; //GetOptionTreeView().TopNode;

            return tnFirst;
        }
        private TreeNode PreviousNode(TreeView tvObject, string SelKey)
        {
            // Function : get tvObject previous node
            TreeNode tnPrev = null;

            if (tvObject.Nodes.Find(SelKey,true)[0].PrevNode != null)         // has previous brother
            {
                if (tvObject.Nodes.Find(SelKey,true)[0].PrevNode.Nodes.Count == 0)
                {
                    tnPrev = tvObject.Nodes.Find(SelKey,true)[0].PrevNode;    // previous brother has no son
                    return tnPrev;
                }
                else
                {
                    tnPrev = tvObject.Nodes.Find(SelKey,true)[0].PrevNode.LastNode;
                    //if (tvObject.Nodes.Find(SelKey, true)[0].PrevNode.Parent == null)
                    //    tnPrev = tvObject.Nodes.Find(SelKey, true)[0].PrevNode;
                    //else
                    //    tnPrev = tvObject.Nodes.Find(SelKey, true)[0].PrevNode.Parent.LastNode;
                    while (tnPrev != null && tnPrev.Nodes.Count > 0)             // previous brother has son , get last son
                    {
                        tnPrev = tnPrev.LastNode;
                    }
                    return tnPrev;
                }
            }
            if (tvObject.Nodes.Find(SelKey, true)[0].Parent == null)            // has no previous brother, and has no parent  , is first one
                tnPrev = null;
            else
                tnPrev = tvObject.Nodes.Find(SelKey,true)[0].Parent;           // is parent
            return tnPrev;
        }
        private TreeNode NextNode(TreeView tvObject, string SelKey)
        {
            // function: get tvObject next node
            TreeNode tnNext = null;

            if (tvObject.Nodes.Find(SelKey, true)[0] != null && tvObject.Nodes.Find(SelKey, true)[0].Nodes.Count != 0)       // has son
            {
                tnNext = tvObject.Nodes.Find(SelKey, true)[0].Nodes[0];
                return tnNext;
            }
            if (tvObject.Nodes.Find(SelKey, true)[0].NextNode != null)       // has no son , but next brother
                tnNext = tvObject.Nodes.Find(SelKey, true)[0].NextNode;
            else
            {
                if (tvObject.Nodes.Find(SelKey, true)[0].Parent == null)
                {
                    tnNext = null;                             // is last one
                    return tnNext;
                }
                else
                {
                    tnNext = tvObject.Nodes.Find(SelKey, true)[0].Parent;
                    while (tnNext.NextNode == null)
                    {
                        if (tnNext.Parent == null)
                        {
                            tnNext = null;                     // is last one
                            return tnNext;
                        }
                        else
                            tnNext = tnNext.Parent;
                    }
                    tnNext = tnNext.NextNode;                 // is parent's next brother
                }
            }
            return tnNext;
        }
        #endregion

        #region delete user defined menu
        public void DelUsermenu(DBAccess dBAccess, string UserMenuName)
        {
            string strSql = string.Empty;

            strSql = "delete from mUserMenu where UserName='" + SysVar.UserName + "' ";
            strSql+= "and upper(UserMenuName)='" + UserMenuName.ToUpper().Replace("'", "''") + "'";
            dBAccess.ExecuteSql(strSql);

        }
        public void DelUsermenu(string UserMenuName)
        {

            DBAccess dBAccess = new DBAccess(false, false);
            DelUsermenu(dBAccess, UserMenuName);
            dBAccess.CloseCon();
        }
        #endregion

        #region Update copy defined menu
        public bool CopyUserMenu(string strUserName, string strMenuName, string strNewMenuName, bool[] bArrSelected)
        {
            bool bCopy = false;
            string strSql = string.Empty;
            int intMenuNo = 0;
            int i = 0;
            DBAccess dBAccess = new DBAccess(false, true);
            DataTable dtUser = null;
            DataRow drUser = null;

            try
            {
                strSql = "select username from muser where username<>'" + strUserName + "'";
                dtUser = dBAccess.GetDataTable(strSql);

                for (i = 0; i< dtUser.Rows.Count; i++)
                {
                    drUser = dtUser.Rows[i];
                    if (bArrSelected[i])
                    {
                        strSql = "delete from musermenu where username='" + drUser["username"].ToString() + "' and usermenuname='" + strNewMenuName + "'";
                        dBAccess.ExecuteSql(strSql);

                        intMenuNo = CvtFunc.ToInt(DataFunctions.GetNextMaxSeqNo(dBAccess, "musermenu", "UserMenuNo", 1, "username='" + drUser["username"].ToString() + "'"));
                        strSql = "INSERT INTO mUserMenu (UserName, UserMenuNo, UserMenuName, UserMenuID, MenuID, MenuName) " +
                                 " select '" + drUser["username"].ToString() + "'," + intMenuNo.ToString() + ",'" + strNewMenuName +
                                 "',UserMenuID, MenuID, MenuName from muserMenu where username='" + strUserName +
                                 "' and usermenuname='" + strMenuName + "'";
                        dBAccess.ExecuteSql(strSql);
                    }
                }
                dBAccess.CommitTranAndCloseCon();
                bCopy = true;
            }
            catch (Exception e)
            {
                dBAccess.RollbackTranAndClose();
                ExceptionManager.ProcessException(e);
            }
            return bCopy;
        }
        #endregion

    }
}
